<?php
/**
 * Copyright (c) 2018-2019.
 *  This file is part of the moonpie production
 *  (c) johnzhang <875010341@qq.com>
 *  This source file is subject to the MIT license that is bundled
 *  with this source code in the file LICENSE.
 */

namespace moonpie\plugin\wechat_account\controller;

use app\common\service\data\QueryDataProvider;
use EasyWeChat\Kernel\Support\Arr;
use moonpie\plugin\wechat_account\model\TemplateModel;
use moonpie\plugin\wechat_account\model\UserTagsModel;
use moonpie\plugin\wechat_account\model\WechatAccount;
use moonpie\plugin\wechat_account\model\WechatAccountUser;
use moonpie\plugin\wechat_account\model\WechatTemplateConfig;
use moonpie\plugin\wechat_account\service\user\CustomWechatUser;

/**
 * 处理公众号配置相关，包括基本配置，缓存配置，模板管理，自定义菜单
 * Class AccountSetting
 * @package moonpie\plugin\wechat_account\controller
 */
class AccountSetting extends AbstractBackendController
{
    protected $beforeActionList = ['checkCurrentAccount'];

    public function profile($account_id)
    {
        /** @var \moonpie\plugin\wechat_account\model\WechatAccount $account */
        $account = $this->request->current_wechat_account;
        $serviceConfig = $account->getServiceConfig();
        $this->_prepareBaseViewVars();
        $this->assign([
            'pageTitle' => '公众号信息',
            'init_config' => json_encode([
                'cacheType' => $serviceConfig->getScopeConfig('caching', 'cacheType'),
                'cacheData' => $serviceConfig->getScopeConfig('caching', 'cacheData', []),
                'saveUrl' => url('wechat_account.admin_save_account_config', ['account_id' => $account_id]),
                'loggingType' => $serviceConfig->getScopeConfig('logging', 'loggingType'),
                'loggingData' => $serviceConfig->getScopeConfig('logging', 'loggingData', []),
            ], JSON_FORCE_OBJECT),
        ]);
        return $this->fetch('#/setting/profile');
    }

    public function serviceConfig($account_id)
    {
        if ($this->request->isPost()) {
            /** @var \moonpie\plugin\wechat_account\model\WechatAccount $account */
            $account = $this->request->current_wechat_account;
            $service = $account->getServiceConfig();
            $result = $service->saveConfig($this->request->post('scope'), $this->request->post('config/a', []));
            if (!$result) {
                $this->error($service->getError());
            }
            $this->success('服务配置信息设置成功');
        }
    }

    /**
     * 展示模板列表部分
     * @param $account_id
     */
    public function templateList($account_id)
    {
        /** @var \moonpie\plugin\wechat_account\model\WechatAccount $account */
        $account = $this->request->current_wechat_account;
        $templateModel = new TemplateModel($account);
        $dataProvider = $templateModel->dataProvider(10);
        //dump($dataProvider);exit;
        $this->_prepareBaseViewVars();
        $this->assign([
            'pageTitle' => '公众号模板消息列表',
            'data_provider' => $dataProvider,
            'try_uri' => 'wechat_account.admin_try_template_send',
            'account_id' => $account_id,
        ]);
        return $this->fetch('#/setting/template');
    }

    public function templateSend($account_id, $tmpl_id)
    {
        /** @var \moonpie\plugin\wechat_account\model\WechatAccount $account */
        $account = $this->request->current_wechat_account;
        $templateModel = new TemplateModel($account);
        $template = $templateModel->findByTmplId($tmpl_id);
        if (empty($template)) {
            $this->error('抱歉指定的模板信息不存在');
        }
        $current_tmpl = $template[0];
        if ($this->request->isPost()) {
            $submit_data = $this->request->post('submit_data/a', []);
            $users = Arr::get($submit_data, 'users', []);
            if (empty($users)) {
                $this->error('请选择发送的用户信息');
            }
            $tmpl_data = Arr::get($submit_data, 'template', []);
            //这里后期需要处理数据库用户部分
            $total = 0;
            foreach ($users as $user) {
                $user_object = new CustomWechatUser($user['id']);
                $response = $templateModel->sendTemplate($user_object, $current_tmpl, $tmpl_data);
                if (Arr::get($response, 'errcode', 100) !== 0) {
                    $this->error(sprintf('为用户发送数据出现错误：%d,已发送成功%d条',
                        Arr::get($response, 'errmsg', '系统未知错误'), $total
                    ));
                }
                $total++;
            }
            $this->success(sprintf('共成功发送%d条记录', $total));
        }
        $this->_prepareBaseViewVars();
        $this->assign([
            'pageTitle' => '公众号模板消息测试发送',
            'tmpl' => $current_tmpl,
            'initConfig' => [

            ]
        ]);
        return $this->fetch('#/setting/template_send');
    }

    /**
     * 展示模板配置列表部分
     * @param $account_id
     */
    public function templateConfigList($account_id)
    {
        /** @var \moonpie\plugin\wechat_account\model\WechatAccount $account */
        //$account = $this->request->current_wechat_account;
        $query = WechatTemplateConfig::where('account_id', $account_id);
        $dataProvider = new QueryDataProvider([
            'query' => $query,
            'paginationConfig' => [
                'listRows' => 15,
            ],
        ]);
        //dump($dataProvider);exit;
        $this->_prepareBaseViewVars();
        $this->assign([
            'pageTitle' => '公众号模板消息配置列表',
            'data_provider' => $dataProvider,
            'account_id' => $account_id,
            'add_url' => url('wechat_account.admin_template_config_manage', ['account_id' => $account_id]),
            'edit_uri' => 'wechat_account.admin_template_config_manage',
        ]);
        return $this->fetch('#/setting/template-config');
    }

    public function templateSenderManage($account_id, $config_id = null)
    {
        /** @var \moonpie\plugin\wechat_account\model\WechatAccount $account */
        $account = $this->request->current_wechat_account;
        $templateModel = new TemplateModel($account);
        $templates = $templateModel->listTemplates();
        if (!$templates) {
            $this->error('抱歉，尚未获取到公众号的模板信息，请先前往公众号添加所需的公众号模板信息');
        }
        $model = new WechatTemplateConfig();
        if ($config_id) {
            $model = $model->where('id', $config_id)->find();
            if (!$model || $model->account_id != $account_id) $this->error('指定规定的信息不存在');
            $is_update = true;
        } else {
            $model->data([
                'account_id' => $account_id,
                'title' => '',
                'description' => '',
                'code' => '',
                'status' => 0,
                'template_id' => '',
                'template_data' => [],
                'template_parser' => '',
            ]);
            $is_update = false;
        }
        if ($this->request->isPost()) {
            //现在开始编写数据存储部分
            $validator = $model->getValidator();
            $data = $this->request->post('submit_data/a', []);
            $result = $validator->check($data);
            if (!$result) {
                $this->error($validator->getError());
            }
            $result = $model->saveRecord($data);
            if (!$result) $this->error($model->getError());
            $this->success('保存数据成功', url('wechat_account.admin_template_config_list', ['account_id' => $account_id]));
        }

        //这里将模板信息配置成select2可识别的数据结构
        $select2_data = array_map(function ($tmpl) use ($model) {
            $return = [
                'id' => $tmpl['template_id'],
                'text' => sprintf('来自于%s-%s的%s', $tmpl['primary_industry'], $tmpl['deputy_industry'], $tmpl['title']),
                'selected' => $model->template_id == $tmpl['template_id'],
                'template' => $tmpl,
            ];
            return $return;
        }, $templates);
        if (!$is_update && !empty($select2_data[0])) {
            $select2_data[0]['selected'] = true;
        }
        $vars = [
            'pageTitle' => $is_update ? '编辑模板消息发送器' : '新增模板消息发送器',
            'initConfig' => [
                'data' => $model->hidden(['create_at', 'update_at', 'status'])->toArray(),
                'templates' => $select2_data,
                'useFrame' => true
            ],
        ];
        $vars['initConfig']['data']['status'] = $model->getData('status');
        $this->assign($vars);
        $this->_prepareBaseViewVars();
        return $this->fetch('#/setting/template-manage');
    }


    /**
     * 粉丝列表页面
     */
    public function fans($account_id, $tag_id = 0)
    {
        $vars = [
            'pageTitle' => '粉丝管理',
        ];
        /** @var \moonpie\plugin\wechat_account\model\WechatAccount $account */
        $account = $this->request->current_wechat_account;
        $userTagsModel = new UserTagsModel($account);
        $tags = $userTagsModel->listTags();
        $all_tag = ['id' => 0, 'name' => '全部用户', 'count' => WechatAccountUser::where('account_id', $account_id)->count()];
        array_unshift($tags, $all_tag);
        $vars['initConfig'] = [
            'tags' => $tags,
            'urlConfig' => [
                'addNewTagUrl' => url('wechat_account.admin_save_new_tag', ['account_id' => $account_id]), //添加新标签的接口
                'syncAllFansUrl' => url('wechat_account.admin_sync_all_fans', ['account_id' => $account_id]),//同步所有粉丝的接口
            ]
        ];
        //接下来，根据用户的微信标签，开始展示粉丝数据
        $model = new WechatAccountUser();
        $model->alias('wau');
        $model->where('wau.account_id', $account_id);
        $model->join('__WECHAT_ACCOUNT_USER_TAGS__ waut', 'waut.wxuser_id = wau.id', 'LEFT');
        if ($tag_id > 0) {
            //关联tag
            $model->where('waut.tag_id', $tag_id);
        }
        $query = $model->field(['wau.nickname', 'wau.avatar', 'wau.id' => 'wxuser_id', 'waut.tag_id', 'wau.subscribe', 'wau.subscribe_at',
            'wau.sex', 'wau.sex' => 'sex_code']);
        $data_provider = new QueryDataProvider(['query' => $query]);
        $data_provider->prepare();
        $vars['data_provider'] = $data_provider;
        $users = $data_provider->getModels();
        $vars['initConfig']['users'] = $users;
        $this->assign($vars);
        $this->_prepareBaseViewVars();
        return $this->fetch('#/fans/fans-list');
    }

    /**
     * 保存新的用户标签
     * @param $account_id
     */
    public function saveNewTag($account_id)
    {
        //@todo 后期记得删除这段代码
        $this->success('', '', [
            'tag' => ['id' => 102, 'name' => '测试标题', 'count' => 100],
        ]);
        /** @var \moonpie\plugin\wechat_account\model\WechatAccount $account */
        $account = $this->request->current_wechat_account;
        $userTagsModel = new UserTagsModel($account);
        $tag = [
            'name' => $this->request->post('tag_name')
        ];
        $error = $this->validate($tag, [
            'name' => 'require|length:1,30',
        ]);
        if (true !== $error) {
            $this->error($error);
        }
        $response = $userTagsModel->createTag($tag['name']);
        if (Arr::has($response, 'tag.id')) {
            $data = array_merge($response, ['count' => 0]);
            $this->success('', '', $data);
        }
        $this->error(Arr::get($response, 'errmsg', '微信请求出现错误'));
    }

    public function syncAllFans($account_id)
    {
        set_time_limit(0);
        $account = $this->getCurrentAccount();
        $gen = $this->syncFans($account);
        $summary = [];
        foreach ($gen as $key => $current) {
            if(is_bool($current) && !$current) {
                $this->error($account->getError());
                break;
            }else if (is_array($current) && Arr::has($current, ['total', 'count'])) {
                $summary = Arr::only($current, ['total', 'count']);
                if ($current['count'] == 10000) {
                    $gen->send($current['next_openid']);
                }
            }
        }
        $this->success('成功同步所有粉丝信息', '', $summary);
    }

    /**
     * 同步粉丝信息
     * @param $service \EasyWeChat\OfficialAccount\Application
     */
    protected function syncFans(WechatAccount $account)
    {
        $next_openid = yield;
        $response = $account->getService()->user->list($next_openid);
        if (Arr::has($response, 'errcode')) {
            $account->setModelError(sprintf('获取公众号用户Openid出现错误:%s', Arr::get($response, 'errmsg', '未知错误')));
            return false;
        }
        $openids = Arr::get($response, 'data.openid', []);
        //分割数据
        $count = Arr::get($response, 'count', 1);
        $size = 100;
        $total_page = ceil($count / $size);
        for($i = 0; $i < $total_page; $i++) {
            $slice_openids = array_slice($openids, $i * $size, $size);
            yield WechatAccountUser::batchSyncFromProfile($account, $slice_openids);
        }
        yield Arr::only($response, ['total', 'count', 'next_openid']);
        if ($response['count'] < 10000) return; //如果当前分页数据小于1万，说明已经检索完成
    }
}
